#pragma once

#include <deque>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>

namespace zl
{
	class Task
	{
	public:
		Task(void* arg = nullptr, void* arg1 = nullptr, const std::string& taskName = "")
			: arg_(arg), arg_1(arg1), taskName_(taskName) {}

		virtual ~Task() {}

		void setArg(void* arg, void* arg1)
		{
			arg_ = arg;
			arg_1 = arg1;
		}

		void setArg1(size_t arg1, const std::string& arg2)
		{
			m_fd_arg = arg1;
			m_url_arg = arg2;
		}

		virtual int run() = 0;

	protected:
		void* arg_;
		void* arg_1;
		std::string taskName_;
		size_t m_fd_arg;
		std::string m_url_arg;
	};

	class ThreadPool
	{
	public:
		ThreadPool(int threadNum = 10);
		~ThreadPool();

		size_t addTask(Task* task);
		void stop();
		int size();
		Task* take();

	private:
		void createThreads();
		void threadFunc();

	private:
		bool isRunning_;
		int threadsNum_;
		std::vector<std::thread> threads_;

		std::deque<Task*> taskQueue_;
		std::mutex mutex_;
		std::condition_variable condition_;
	};
}